package it.polimi.swKnights.SWIMv2.ejb.administration;

import java.util.Date;

import it.polimi.swKnights.SWIMv2.ejb.authentication.LoginHandlerLocal;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.Admin;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.Founder;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.RegisteredUser;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.AlreadyAdminException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidLoginPrivilegesException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.LoginFailException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.NoSelfRemoveException;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;

/**
 * Session Bean implementation class NominateAdmin
 */
@Stateless
public class NominateAdmin extends AdministrationBean implements
		NominateAdminRemote
{
	@EJB
	private LoginHandlerLocal loginController;

	@PersistenceContext(unitName = "swimv2-manager")
	private EntityManager manager;

	@Override
	public void nominateNewAdmin(String user, String founder, String password)
			throws LoginFailException, InvalidLoginPrivilegesException,
			AlreadyAdminException
	{
		this.loginController.checkLoginDataAndPrivileges(founder, password,
				Founder.class);
		this.handleNewAdmin(user);
	}

	@Override
	public void removeFromAdmins(String user, String founder, String password)
			throws LoginFailException, InvalidLoginPrivilegesException,
			NoSelfRemoveException
	{
		this.loginController.checkLoginDataAndPrivileges(founder, password,
				Founder.class);
		if (user.equals(founder))
			throw new NoSelfRemoveException();
		this.deleteAdmin(user);
	}

	private void handleNewAdmin(String user) throws AlreadyAdminException
	{
		if (manager.find(Admin.class, user) == null)
		{
			RegisteredUser oldUser = this.getUserEntity(RegisteredUser.class,
					user);
			Admin newAdmin = null;

			try
			{
				newAdmin = this.createUser(oldUser, Admin.class);
			}
			catch (Exception e)
			{
				System.err.println("Error in new admin creation");
				e.printStackTrace();
			}

			newAdmin.setTookOver(new Date());
			this.manager.remove(oldUser);
			this.manager.persist(newAdmin);

		}
		else
		{
			throw new AlreadyAdminException("user " + user

			+ " already admin");
		}

	}

	private void deleteAdmin(String user)
	{
		Admin admin = this.getUserEntity(Admin.class, user);
		RegisteredUser newUser = null;

		try
		{
			newUser = this.createUser(admin, RegisteredUser.class);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			System.err.println("Errore in delete admin");
		}

		this.manager.remove(admin);
		this.manager.persist(newUser);

	}

	private <T> T getUserEntity(Class<T> clazz, String userName)
	{
		T user = this.manager.find(clazz, userName);
		if (user == null)
			throw new EntityNotFoundException();
		else
			return user;
	}

}
